package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.StrategyCatalog;
import cn.wolfcode.wolf2w.domain.UserFavor;
import cn.wolfcode.wolf2w.query.StrategyQueryObject;
import cn.wolfcode.wolf2w.redis.service.IStatisVORedisService;
import cn.wolfcode.wolf2w.repository.StrategyRepository;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.service.IUserFavorService;
import cn.wolfcode.wolf2w.util.DBHelper;
import cn.wolfcode.wolf2w.vo.StrategyCatologVO;
import cn.wolfcode.wolf2w.vo.StrategyStatisVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class StrategyServiceImpl implements IStrategyService {

    @Autowired
    private StrategyRepository strategyRepository;

    @Autowired
    private MongoTemplate template;

    @Autowired
    private IStatisVORedisService statisVORedisService;

    @Autowired
    private IUserFavorService userFavorService;


    @Override
    public void save(Strategy strategy) {
        strategy.setId(null);
        strategyRepository.save(strategy);
    }

    @Override
    public void delete(String id) {
        strategyRepository.deleteById(id);
    }

    @Override
    public void update(Strategy strategy) {
        strategyRepository.save(strategy);
    }

    @Override
    public Strategy get(String id) {
        return strategyRepository.findById(id).orElse(null);
    }

    @Override
    public List<Strategy> list() {
        return strategyRepository.findAll();
    }

    @Override
    public Page<Strategy> query(StrategyQueryObject qo) {
        Query query = new Query();
        if(StringUtils.hasLength(qo.getDestId())) {
            query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
        }
        if(StringUtils.hasLength(qo.getThemeId())) {
            query.addCriteria(Criteria.where("themeId").is(qo.getThemeId()));
        }
        if(qo.getState() != -1) {
            query.addCriteria(Criteria.where("state").is(qo.getState()));
        }
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        return DBHelper.query(template, qo, query, pageable, Strategy.class);
    }

    @Override
    public List<StrategyCatologVO> queryStrategyCatolog() {
        List<StrategyCatologVO> list = new ArrayList<>();
        TypedAggregation<StrategyCatalog> agg = Aggregation.newAggregation(StrategyCatalog.class,
                Aggregation.group("destName")
                        .push("name").as("names")
                        .push("id").as("ids"));

        AggregationResults<Map> maps = template.aggregate(agg, Map.class);
        List<Map> mapList = maps.getMappedResults();
        for (Map map : mapList) {
            StrategyCatologVO strategyCatologVO = new StrategyCatologVO();
            strategyCatologVO.setDestName(map.get("_id").toString());
            List<Object> names = (List<Object>) map.get("names");
            List<Object> ids = (List<Object>) map.get("ids");
            List<StrategyCatalog> catalogList = new ArrayList<>();
            for (int i = 0; i < names.size(); i++) {
                StrategyCatalog strategyCatalog = new StrategyCatalog();
                strategyCatalog.setName(names.get(i).toString());
                strategyCatalog.setId(ids.get(i).toString());
                catalogList.add(strategyCatalog);
            }
            strategyCatologVO.setCatalogList(catalogList);
            list.add(strategyCatologVO);
        }
        return list;
    }

    @Override
    public List<Strategy> getStrategyByCatalogId(String id) {
        return strategyRepository.findByCatalogId(id);
    }

    @Override
    public List<Strategy> getStrategiesTop3ByDestId(String id) {
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.ASC, "viewNum");
        return strategyRepository.findByDestId(id, pageable);
    }

    @Override
    public void changeState(int state, String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("state", state);
        template.updateFirst(query, update, Strategy.class);
    }

    @Override
    public StrategyStatisVo getStrategyStatisVo(String sid) {
        return statisVORedisService.getStrategyStatisVoById(sid);
    }

    @Override
    public void updateStrategyStatisByVo(StrategyStatisVo vo) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(vo.getStrategyId()));
        Update update = new Update();
        update.set("viewnum", vo.getViewnum());
        update.set("replynum", vo.getReplynum());
        update.set("favornum", vo.getFavornum());
        update.set("sharenum", vo.getSharenum());
        update.set("thumbsupnum", vo.getThumbsupnum());

        // 调用template 执行update方法
        template.updateFirst(query, update, Strategy.class);
    }

}
